﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Office.Interop.Excel;
using System.Text.RegularExpressions;
using System.Windows;
using BAL.PublishSharepoint;
using DAL.EstRec;
using BAL.EstRec.HQConsolidacion;
using System.Collections.ObjectModel;
using BAL.EstRec.Common;

namespace BAL.EstRec
{
    public class CosolidaHQ
    {
        public string pathDownload { get; set; }
        public string pathLocal { get; set; }
        public string pathProcessed { get; set; }
        public long unidVersion { get; set; }
        public ObservableCollection<LogMsg> log;
        public CierreConsolidacion cierre;
  
        public CosolidaHQ(AppConfs conf,long unidVersion,IDlgLoaderDataContext dc)
        {
            this.pathDownload = conf.cnf.SharedFolderFDV;
            this.pathLocal = conf.cnf.CierreConsolidacionLocal;
            this.pathProcessed = conf.cnf.ProcConsolidacionLocal;
            this.unidVersion = unidVersion;
            this.log = new ObservableCollection<LogMsg>();
            try
            {
                this.cierre = new CierreConsolidacion(this.unidVersion.ToString(),conf);
            }
            catch (Exception ex)
            {
                ;
            }
        }
      
        private void actualizaHQ(string unidVersion)
        {
            ListaCapturaPivot list;

            List<string> listFile = new List<string>();

            List<string> newListFile = new List<string>();

            List<string> idfecha = new List<string>();

            //List<string> idss = new List<string>();

            string[] fileDownload;

            try
            {
                #region logica para la descarga de archivos a ruta local
                fileDownload = Directory.GetFiles(this.pathDownload);

                if (!this.pathDownload.Equals(""))
                {
                    foreach (string fileNameDownload in fileDownload)
                    {

                        string[] files = Regex.Split(fileNameDownload, @"\\");

                        foreach (var item in files.Reverse())
                        {

                            string[] unidVersionExel = Regex.Split(item, @"_");

                            foreach (var it in unidVersionExel)
                            {
                                if (it == unidVersion)
                                {
                                    if (File.Exists(this.pathLocal + item))
                                    {
                                        File.Delete(this.pathLocal + item);
                                        File.Copy(fileNameDownload, this.pathLocal + item);
                                    }
                                    else
                                    {
                                        File.Copy(fileNameDownload, this.pathLocal + item);
                                    }
                                    //agrega a la lista los ducumentos de carpeta local(ConsolidacionHQ) 
                                    idfecha.Add(item);
                                    listFile.Add(this.pathLocal + item);
                                    break;
                                }//foreach
                            }
                            break;
                        }//foreach
                    }//foreach

                }
                #endregion
                #region logica para los ducmentos mas actuales no terminado

                //if (idfecha.Count > 0)
                //{

                //    var soldOutProducts =
                //    from p in idfecha
                //    select new { idVersion = p.Split('_')[0], idRecurso = p.Split('_')[1], fecha = p.Split('_')[0] };

                //    var orderGroups =
                //    from p in idfecha
                //    group p by p.Split('_')[0] into g
                //    select new { idVersion = g, fecha = g };

                     
                //}
                //string re = "";
                //string re2 = "";
                //string fe = "";
                //string fe2 = "";                   
                
                //if (listFile.Count>0)
                //{
                //    //listFile.Sort();
                //    for (int i = 0; i < listFile.Count; i++)
                //    {

                //        string name = listFile[i];
                //        string[] archivo = Regex.Split(name, @"\\");
                //        foreach (string item in archivo.Reverse())
                //        {
                //            string[] nomArchive = Regex.Split(item, @"_");

                //            int c = 0;
                //            foreach (var fecha in nomArchive)
                //            {
                                
                //                if (c == 1)
                //                {
                //                    re = fecha;
                //                }
                //                if (c == 2)
                //                {
                //                    fe = fecha;
                //                }
                //                c += 1;

                //            }
                //            c = 0;
                //            break;
                //        }
                //        //Segundo ciclo

                //        for (int j = 1; j < listFile.Count; j++)
                //        {

                //            string name2 = listFile[j];

                //            string[] archivo2 = Regex.Split(name2, @"\\");
                //            foreach (string item in archivo2.Reverse())
                //            {
                //                string[] nomArchive = Regex.Split(item, @"_");
                //                int c = 0;
                //                foreach (var fecha in nomArchive)
                //                {
                //                    if (c == 1)
                //                    {
                //                        re2 = fecha;
                //                    }
                //                    if (c == 2)
                //                    {
                //                        fe2 = fecha;
                //                    }
                //                    c += 1;
                //                }
                //                c = 0;
                //                bool existe = false;

                //                existe= comparaArchivos(re, fe, re2, fe2);
                //                if (existe==true)
                //                {
                //                    newListFile.Add(name2); 
                //                }
                                
                //                break;
                //            }

                //        }

                //    }
                    
                //}
                
                #endregion
                
                #region logica para la actualizar o insertar en la tabla de HQ
                if (listFile.Count > 0)
                {
                    foreach (string fileName in listFile)
                    {
                        list = new ListaCapturaPivot(fileName);

                        //METODO QUE LEE LOS EXCEL
                        try
                        {
                            list.GenerarLista();
                            //this.UpdateConfirmed(unidVersion);
                            //metodo que actuliza o inserta
                            CapturaHQ.UpdateConsolidacionHQ(list.ListaElementos, unidVersion);
                        }
                        catch (Exception)
                        {
                            continue;
                        }

                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                //MessageBox.Show("");
                MessageBox.Show("No hay archivos para descargar", "Mensaje del Sistema", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
             
        }
        public void consolidacionHQ(string unidVersion) 
        {
            AppConfs cn = new AppConfs();
            
            System.Data.DataTable dt = GetPathsSP();    //Obtiene las rutas de publicación en workpoint desde el catálogo de Recurso

            if (dt.Rows.Count > 0)
            {

                foreach (System.Data.DataRow item in dt.Rows)
                {
                    try
                    {
                        string lib = item["PATH_PUBLICACION"].ToString().Split('/').Last();
                        string contexto = item["PATH_PUBLICACION"].ToString().Replace(lib, "");

                        // descarga archivos de workpoint
                        //PublishSP.DownloadFilesFromSP(contexto, lib, this.pathLocal,unidVersion);

                        // TODO: Seleccionar el archivo más reciente por versión y recurso. Actualmente descarga todos los archivos de la carpeta
                        actualizaHQ(unidVersion);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }//if
        }
        public void consolidate(IDlgLoaderDataContext dc)
        {
            try
            {
                //Descargar archivos de workpoint
                dc.Message = "Descargando archivos de Workpoint";
                
                //this.downloadFromWrokpoint();
                
                //Descargar archivos de carpeta compartida
                dc.Message = "Descargando archivo de carpeta compartida";
                this.downloadLastestFiles();
                
                //Consolidar archivos en carpeta local de la version actual
                dc.Message = "Consolidando información...";
                this.consolidateVersion();


                //Actualizar en la base que la versión ha sido consolidad
                this.cierre.MetodoConsolida();

                dc.Message = "Proceso finalizado";
            }
            catch (Exception ex)
            {
                dc.ManualClose = true;
                dc.Message = "Error : "+ex.Message;
                this.log.Add(new LogMsg("Error en la consolidación : " + ex.Message + " - - inner: " + ex.InnerException, 1));
            }
        }

        /// <summary>
        /// Descarga los archivos del la carpeta del servidor.
        /// Se asume que todos los archivos a descargar son de extension xlsx
        /// </summary>
        /// <param name="files">Colección de ConsolidacionFileInfo</param>
        /// <param name="sourcePath">Path de servidor / carpeta compartida</param>
        /// <param name="destPath">Path de destino, donde son colocalos los archivos</param>
        private void downloadLastestFiles()
        {
            //Se asume que files son todos de extensión xlsx
            List<ConsolidacionFileInfo> files;
            string sourcePath = this.pathDownload;
            string destPath = this.pathLocal;
            this.log.Add(new LogMsg("Descar de archivos desde ruta : "+sourcePath,0 ));
            string extension=".xlsx";
            string tmpSource = "";
            string tmpDest = "";

            try
            {
                files = this.getDownloadFileList();
            }
            catch (Exception ex)
            {
                throw ex;
            }


            foreach (ConsolidacionFileInfo f in files)
            {
                try
                {
                    tmpSource = f.UnidVersion.ToString() + "_" + f.IdRecurso + "_" + f.DateLoaded.ToString() + extension;
                    this.log.Add(new LogMsg("Descagando archivo : " + tmpSource, 0));
                    tmpSource = sourcePath + tmpSource;

                    tmpDest=destPath+ f.UnidVersion.ToString() + "_" + f.IdRecurso + "_" + f.DateLoaded.ToString() + extension;
                    File.Copy(tmpSource, tmpDest);
                    

                    this.log.Add(new LogMsg("Archivo descargado", 0));
                    
                }
                catch (Exception ex)
                {
                    this.log.Add(new LogMsg("Error : " + ex.Message+" - inner: "+ex.InnerException, 1));
                    throw ex;
                }
            }
        }

        /// <summary>
        /// Carga a la de HQBgt el archivo especificado.
        /// La información del archivo es cargada en la columna confirmed.
        /// </summary>
        /// <param name="fullFilePath">Nombre completa (con ruta) del archivo; xm : c:\test\lol\20121012142150863_r1_20121012142150864.xlsx</param>
        private void consolidateFile(string fullFilePath)
        {
            ListaCapturaPivot list;

            if (!String.IsNullOrEmpty(fullFilePath))
            {
                this.log.Add(new LogMsg("Consolidando archivo " + fullFilePath.Split('\\').Last(), 0));
                try
                {
                    list = new ListaCapturaPivot(fullFilePath);
                    list.GenerarLista();
                    
                    CapturaHQ.UpdateConsolidacionHQ(list.ListaElementos,this.unidVersion.ToString());
                    this.log.Add(new LogMsg("Archivo consolidado.", 0));
                }
                catch (Exception ex)
                {
                    this.log.Add(new LogMsg("Error al leer archivo : " + fullFilePath.Split('\\').Last()+"; err: "+ex.Message, 0));
                }
            }
            else
            {
                this.log.Add(new LogMsg("El nombre del archivo es vacío, inválido o no pertenece a unidVersion: "+this.unidVersion.ToString(), 0));
            }
        }

        /// <summary>
        /// Consolida los archivos que se encuentren en pathLocal filtrado por unidVersion
        /// </summary>
        private void consolidateVersion()
        {
            try
            {
                this.log.Add(new LogMsg("Consolidar archivos de version : " + this.unidVersion.ToString(), 0));
                //Obtener el listado de archivos filtrado por unidVersion
                string[] list = this.getFileListByUnid(this.pathLocal, this.unidVersion);
                List<ConsolidacionFileInfo> l = this.getLastLocalVersionFileByUnid();

                string tmpSource;
                string extension = ".xlsx";
                CapturaHQ.UpdateConfirmed(unidVersion.ToString());
                foreach (ConsolidacionFileInfo f in l)
                {
                    tmpSource = f.UnidVersion.ToString() + "_" + f.IdRecurso + "_" + f.DateLoaded.ToString() + extension;
                    tmpSource = this.pathLocal + tmpSource;
                    this.consolidateFile(tmpSource);
                    this.moveToProcessed(f.UnidVersion.ToString() + "_" + f.IdRecurso + "_" + f.DateLoaded.ToString() + extension);
                }
            }
            catch (Exception ex)
            {
                this.log.Add(new LogMsg("Error al consolidar version : " + ex.Message+" inner: "+ex.InnerException, 0));
            }
        }

        private void moveToProcessed(string fileName)
        {
            try
            {
                File.Copy(this.pathLocal + fileName, this.pathProcessed + fileName,true);
                File.Delete(this.pathLocal + fileName);
            }
            catch (Exception ex)
            {
                ;
            }
        }

        private List<ConsolidacionFileInfo> getDownloadFileList()
        {
            List<ConsolidacionFileInfo> resultList=null;

            //Obtener lista del servidor de los archivos mas recientes
            List<ConsolidacionFileInfo> serverList = this.getLastVersionFileByUnid();

            //Obtener lista de los archivos mas recientes de la carpeta local de procesados
            List<ConsolidacionFileInfo> localList = this.getLastProcessedVersionFileByUnid();

            //Obtener los archivos que no existen 
            resultList = (from s in serverList
                      from l in localList.Where(o => o.UnidVersion == s.UnidVersion && o.IdRecurso == s.IdRecurso && o.DateLoaded==s.DateLoaded).DefaultIfEmpty()
                      where l == null
                      select s).ToList();

            return resultList;
        }

        private List<ConsolidacionFileInfo> getLastProcessedVersionFileByUnid()
        {
            string tmp = this.pathDownload;
            this.pathDownload = this.pathProcessed;
            List<ConsolidacionFileInfo> localList = this.getLastVersionFileByUnid();
            this.pathDownload = tmp;
            return localList;
        }

        private List<ConsolidacionFileInfo> getLastLocalVersionFileByUnid()
        {
            string tmp = this.pathDownload;
            this.pathDownload = this.pathLocal;
            List<ConsolidacionFileInfo> localList = this.getLastVersionFileByUnid();
            this.pathDownload = tmp;
            return localList;
        }

        private List<ConsolidacionFileInfo> getLastVersionFileByUnid()
        {
            string dirPath=this.pathDownload;
            long unidVersion = this.unidVersion;
            List<ConsolidacionFileInfo> cfi = null;

            //Obtener lista de archivos
            try
            {
                cfi=new List<ConsolidacionFileInfo>();
                string[] arr = this.getFileListByUnid(dirPath, unidVersion);

                arr.ToList().ForEach(a =>
                {
                    try
                    {
                        cfi.Add(new ConsolidacionFileInfo(Convert.ToInt64(a.Split('\\').Last().Split('_')[0]), a.Split('\\').Last().Split('_')[1], Convert.ToInt64(a.Split('\\').Last().Split('_')[2].Split('.')[0] )));
                    }
                    catch (Exception ex0)
                    {
                        ;
                    }
                });

                //Obtener la versión mayor
                var res = (from c in cfi
                           group c by new 
                           {
                               c.UnidVersion,
                               c.IdRecurso,
                           } into g
                           select new ConsolidacionFileInfo()
                           {
                               UnidVersion = g.Key.UnidVersion
                               ,
                               IdRecurso = g.Key.IdRecurso
                               ,
                               DateLoaded = g.Max(s => s.DateLoaded)
                           }).ToList < ConsolidacionFileInfo>();
                cfi = res;

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return cfi;
        }

        private string[] getFileListByUnid(string dirPath,long unidVersion)
        {
            string[] arr = null;

            try
            {
                arr = Directory.GetFiles(dirPath);
                var res = (from a in arr
                          where a.Split('\\').Last().Split('_')[0].ToString().ToLower() == unidVersion.ToString().ToLower()
                           select a).ToArray<string>(); ;
                arr = res;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return arr;
        }

        private System.Data.DataTable GetPathsSP()
        {
            string query = "SP_ER_GET_SPPATHS";
            System.Data.DataTable dt = new System.Data.DataTable();
            try
            {
                dt = SrvDB.ExecuteQuery(query);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return dt;
        }

        private void downloadFromWrokpoint()
        {
            //AppConfs cn = new AppConfs();

            System.Data.DataTable dt = GetPathsSP();    //Obtiene las rutas de publicación en workpoint desde el catálogo de Recurso

            if (dt.Rows.Count > 0)
            {

                foreach (System.Data.DataRow item in dt.Rows)
                {
                    try
                    {
                        string lib = item["PATH_PUBLICACION"].ToString().Split('/').Last();
                        string contexto = item["PATH_PUBLICACION"].ToString().Replace(lib, "");
                        PublishSP sp = new PublishSP(contexto, lib, this.unidVersion.ToString(), this.pathLocal);
                        sp.DownloadFilesFromSP();
                        
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }//if
        }//
    }
}
